/*
* ========== Copyright Header Begin ==========================================
* 
* OpenSPARC T1 Processor File: initconfig.c
* Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* 
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* 
* The above named program is distributed in the hope that it will be 
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* General Public License for more details.
* 
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* 
* ========== Copyright Header End ============================================
*/
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

#include <assert.h>

#include "basics.h"
#include "allocate.h"
#include "simcore.h"
#include "config.h"
#include "options.h"
#include "fileutil.h"
#include "lexer.h"




	/*
	 * The parser is the first pass through the configuration.
	 * This is the second pass, and builds all the support data
	 * structures and virtual function pointers that the simulator
	 * is going to require.
	 */



static void init_system(system_t * systemp);
static void init_domain(domain_t * domain);



	/*
	 * This function initializes the simualtor configuration
	 * parse the config and state files.
	 */

void init_config()
{
	int idx;

DBG(	printf("init_config()\n"); );

		/* Initialise the systems within this config
		 */
	for (idx=0; idx<target_config.systems.count; idx++) {
		system_t * systemp;

		systemp = LIST_ENTRY( target_config.systems, idx );

DBG(		printf("init system %d : \"%s\"\n", idx, systemp->namep); );

		init_system(systemp);
	}
}







	/*
	 * Initialise the components of a given system, then
	 * the appropriate info for itself.
	 */

void init_system(system_t * systemp)
{
	int idx;

	for (idx=0; idx<systemp->domains.count; idx++) {
		domain_t * domainp;

		domainp = LIST_ENTRY( systemp->domains, idx );

DBG(		printf("init_system: domain %d\n",
			domainp->idx); );

		init_domain(domainp);

	}
}



	/*
	 * OK, initialise the components of a domain -
	 * IO/mem devices, and CPUs.
	 */

void init_domain(domain_t * domainp)
{
	config_dev_t * config_devp;
	int idx;

	for (idx=0; idx<domainp->procs.count; idx++) {
		proc_type_t * proc_typep;
		config_proc_t * config_procp;

		config_procp = LIST_ENTRY( domainp->procs, idx );
		proc_typep = config_procp->proc_typep;

		assert( proc_typep->proc_magic == CPU_MAGIC );

DBG(		printf("init_domain: proc %d : %s\n",
			config_procp->proc_id, proc_typep->proc_type_namep); );

			/* based on the proc type we call the proc-dependent init */
		proc_typep->init_proc(domainp, config_procp);
	}


	config_devp = domainp->device.listp;
	for (idx=0; idx<domainp->device.count; idx++) {
		dev_type_t * dev_typep;

		dev_typep = config_devp->dev_typep;

DBG(		printf("init_domain: device %d : %s : 0x%llx + 0x%llx\n",
			config_devp->device_id, dev_typep->dev_type_namep,
			config_devp->addrp->baseaddr,
			config_devp->addrp->topaddr - config_devp->addrp->baseaddr); );

		assert( dev_typep->dev_magic == DEV_MAGIC );

		dev_typep->init_dev(config_devp);

		config_devp = config_devp->nextp;
	}
}




